module klang.ir.转换工厂.转换工具.IR转换工具_;
import 全局;
import std.functional: ·fd = toDelegate;
import ··类型_ = klang.编译.类型.类型_;
import klang.编译.路径.路径_: 获取正规化路径组件组, 获取路径从路径组件组, 获取正规化绝对路径, 组合路径, 文件扩展名是, 获取相对路径从目录, 相对路径, 目录分割符;
import klang.ir.语法节点.IR节点_: 源文件_ = IR源文件_;
import klang.ir.类型.IR类型_: 编译选项_;
import klang.编译.类型.类型_: 程序主机接口_;
import klang.编译.核心.核心_: 循环每个, 最小, 获取正规文件名函数_, 查找索引, 结尾包含;
dstring 获取输出文件名(源文件_ n, 程序主机接口_ 主机, 编译选项_ 编译选项, dstring 新扩展) {
    dstring 输出目录 = "./测试/输出"d;
    dstring 公共目录 = .计算源文件的公共目录([n.文件名], 主机.获取当前目录(), cast(获取正规文件名函数_)(·fd(&主机.getCanonicalFileName)));
    dstring 文件名 = .获取源文件名在新目录(n.文件名, 输出目录, 主机.获取当前目录(), 公共目录, cast(获取正规文件名函数_)(·fd(&主机.getCanonicalFileName)));
    文件名 = .删除文件扩展(文件名, 主机);
    文件名 ~= 新扩展;
    return 文件名;
}
dstring 删除文件扩展(dstring path, 程序主机接口_ 主机) {
    dstring[] 扩展组 = 主机.获取前端().获取支持的扩展();
    foreach (dstring e; 扩展组) {
        dstring 结果 = .尝试删除扩展(path, e);
        if (结果 != ""d) {
            return 结果;
        }
    }
    return path;
}
dstring 尝试删除扩展(dstring path, dstring extension) {
    if (文件扩展名是(path, extension)) {
        return .删除扩展(path, extension);
    }
    return ""d;
}
dstring 删除扩展(dstring path, dstring extension) {
    return path[0 .. (path.length - extension.length)];
}
dstring 获取源文件名在新目录(dstring fileName, dstring newDirPath, dstring currentDirectory, dstring commonSourceDirectory, 获取正规文件名函数_ getCanonicalFileName) {
    dstring sourceFilePath = 获取正规化绝对路径(fileName, currentDirectory);
    bool 是在公共目录内 = 查找索引(getCanonicalFileName(sourceFilePath), getCanonicalFileName(commonSourceDirectory)) == 0;
    sourceFilePath = 是在公共目录内 ? sourceFilePath[commonSourceDirectory.length .. $] : sourceFilePath;
    return 组合路径(newDirPath, [sourceFilePath]);
}
dstring 计算源文件的公共目录(dstring[] fileNames, dstring currentDirectory, 获取正规文件名函数_ getCanonicalFileName) {
    dstring[] 结果路径组件;
    bool 失败了 = 循环每个!(dstring, bool)(fileNames, (dstring sourceFile, size_t _) {
        // Each file contributes into common source file path
        dstring[] 源文件路径组件 = 获取正规化路径组件组(sourceFile, currentDirectory);
        源文件路径组件.length = 源文件路径组件.length - 1;
        if (结果路径组件 is ··null!(dstring[])) {
            // first file
            结果路径组件 = 源文件路径组件;
            return false;
        }
        long n = 最小(结果路径组件.length, 源文件路径组件.length);
        {
            for (int i = 0; i < n; ++i) {
                if (getCanonicalFileName(结果路径组件[i]) != getCanonicalFileName(源文件路径组件[i])) {
                    if (i == 0) {
                        // Failed to find any common path component
                        return true;
                    }
                    // New common path found that is 0 -> i-1
                    结果路径组件.length = i;
                    break;
                }
            }
        }
        // If the 源文件路径组件 was shorter than the 结果路径组件, truncate to the 源文件路径组件
        if (源文件路径组件.length < 结果路径组件.length) {
            结果路径组件.length = 源文件路径组件.length;
        }
        return false;
    });
    // A common path can not be found when paths span multiple drives on windows, for example
    if (失败了) {
        return ""d;
    }
    dstring[] ···temp·0·_1 = 结果路径组件;
    if (···temp·0·_1 is ··null!(dstring[])) { // Can happen when all input files are .d.ts files
        return currentDirectory;
    }
    dstring 结果 = 获取路径从路径组件组(结果路径组件);
    if (!结尾包含(结果, 目录分割符)) {
        结果 ~= 目录分割符;
    }
    return 结果;
}
